package com.aizuda.easyManagerTool.domain.tuple;

import java.util.Arrays;
import java.util.Objects;
import java.util.Random;
import java.util.stream.Collectors;

public final class StringUtils {
    public static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String byteToHexString(byte[] bytes, int start, int end) {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes == null");
        } else {
            int length = end - start;
            char[] out = new char[length * 2];
            int i = start;

            for(int j = 0; i < end; ++i) {
                out[j++] = HEX_CHARS[(240 & bytes[i]) >>> 4];
                out[j++] = HEX_CHARS[15 & bytes[i]];
            }

            return new String(out);
        }
    }

    public static String byteToHexString(byte[] bytes) {
        return byteToHexString(bytes, 0, bytes.length);
    }

    public static byte[] hexStringToByte(String hex) {
        byte[] bts = new byte[hex.length() / 2];

        for(int i = 0; i < bts.length; ++i) {
            bts[i] = (byte)Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }

        return bts;
    }

    public static String arrayAwareToString(Object o) {
        String arrayString = Arrays.deepToString(new Object[]{o});
        return arrayString.substring(1, arrayString.length() - 1);
    }

    public static String showControlCharacters(String str) {
        int len = str.length();
        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < len; ++i) {
            char c = str.charAt(i);
            switch (c) {
                case '\b':
                    sb.append("\\b");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\u000b':
                default:
                    sb.append(c);
                    break;
                case '\f':
                    sb.append("\\f");
                    break;
                case '\r':
                    sb.append("\\r");
            }
        }

        return sb.toString();
    }

    public static String getRandomString(Random rnd, int minLength, int maxLength) {
        int len = rnd.nextInt(maxLength - minLength + 1) + minLength;
        char[] data = new char[len];

        for(int i = 0; i < data.length; ++i) {
            data[i] = (char)(rnd.nextInt(32767) + 1);
        }

        return new String(data);
    }

    public static String getRandomString(Random rnd, int minLength, int maxLength, char minValue, char maxValue) {
        int len = rnd.nextInt(maxLength - minLength + 1) + minLength;
        char[] data = new char[len];
        int diff = maxValue - minValue + 1;

        for(int i = 0; i < data.length; ++i) {
            data[i] = (char)(rnd.nextInt(diff) + minValue);
        }

        return new String(data);
    }

    private static char nextAlphanumericChar(Random rnd) {
        int which = rnd.nextInt(62);
        char c;
        if (which < 10) {
            c = (char)(48 + which);
        } else if (which < 36) {
            c = (char)(55 + which);
        } else {
            c = (char)(61 + which);
        }

        return c;
    }

    public static boolean isNullOrWhitespaceOnly(String str) {
        if (str != null && str.length() != 0) {
            int len = str.length();

            for(int i = 0; i < len; ++i) {
                if (!Character.isWhitespace(str.charAt(i))) {
                    return false;
                }
            }

            return true;
        } else {
            return true;
        }
    }



    public static String toQuotedListString(Object[] values) {
        return (String)Arrays.stream(values).filter(Objects::nonNull).map((v) -> {
            return v.toString().toLowerCase();
        }).collect(Collectors.joining(", ", "\"", "\""));
    }

    private StringUtils() {
    }
}
